package com.orangeforms.webadmin.app.controller;

import cn.hutool.core.util.ReflectUtil;
import com.github.pagehelper.page.PageMethod;
import com.orangeforms.common.core.annotation.MyRequestBody;
import com.orangeforms.common.core.constant.ErrorCodeEnum;
import com.orangeforms.common.core.object.*;
import com.orangeforms.common.core.upload.BaseUpDownloader;
import com.orangeforms.common.core.upload.UpDownloaderFactory;
import com.orangeforms.common.core.upload.UploadResponseInfo;
import com.orangeforms.common.core.upload.UploadStoreInfo;
import com.orangeforms.common.core.util.MyCommonUtil;
import com.orangeforms.common.core.util.MyModelUtil;
import com.orangeforms.common.core.util.MyPageUtil;
import com.orangeforms.common.log.annotation.OperationLog;
import com.orangeforms.common.log.model.constant.SysOperationLogType;
import com.orangeforms.common.redis.cache.SessionCacheHelper;
import com.orangeforms.webadmin.app.dto.PaperExerciseTransDto;
import com.orangeforms.webadmin.app.model.PaperExerciseTrans;
import com.orangeforms.webadmin.app.service.PaperExerciseTransService;
import com.orangeforms.webadmin.app.vo.PaperExerciseTransVo;
import com.orangeforms.webadmin.config.ApplicationConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * OrangeSingleDemo PaperExerciseTransController class
 *
 * @author xisheng
 * @date 2022/06/06
 */
@Slf4j
@RestController
@RequestMapping("/admin/app/orgPaper")
public class PaperExerciseTransController {

    @Autowired
    private PaperExerciseTransService paperExerciseTransService;
    @Autowired
    private ApplicationConfig appConfig;
    @Autowired
    private SessionCacheHelper cacheHelper;
    @Autowired
    private UpDownloaderFactory upDownloaderFactory;

   @PostMapping("/list")
   public ResponseResult<MyPageData<PaperExerciseTransVo>> list(
           @MyRequestBody PaperExerciseTransDto orgPaperDtoFilter,
           @MyRequestBody MyOrderParam orderParam,
           @MyRequestBody MyPageParam pageParam
           ) {

       log.info("打印 -- PaperExerciseTransController");
       if(pageParam != null) {
           PageMethod.startPage(pageParam.getPageNum(),pageParam.getPageSize());
       }

       if(orgPaperDtoFilter!=null){
           log.info("打印 FilterDto :{}",orgPaperDtoFilter.toString());
       }else {
           log.info("FilterDto 为 null");
       }



       PaperExerciseTrans paperExerciseTransFilter = MyModelUtil.copyTo(orgPaperDtoFilter,PaperExerciseTrans.class);
       String orderBy = MyOrderParam.buildOrderBy(orderParam,PaperExerciseTrans.class);

       if(orderParam != null){
           log.info("打印orgPaper orderParam:{}",orderParam.toString());
       }

       log.info("打印 -- paperExerciseTransList orderBy:{}",orderBy);
       List<PaperExerciseTrans> paperExerciseTransList = paperExerciseTransService
               .getPaperExerciseTransListWithRelation(paperExerciseTransFilter,orderBy);

       log.info("打印DeviceTypeDictMap字典:{}",paperExerciseTransList.get(0).getDeviceTypeDictMap());
       log.info("打印SchoolIdDictMap字典:{}",paperExerciseTransList.get(0).getSchoolIdDictMap());

       ResponseResult<MyPageData<PaperExerciseTransVo>> responseResult =  ResponseResult.success
               (MyPageUtil.makeResponseData(paperExerciseTransList, PaperExerciseTrans.INSTANCE));

       List<PaperExerciseTransVo> paperExerciseTransVoList = responseResult.getData().getDataList();
       log.info("打印TransVoList字典:{}",paperExerciseTransVoList.get(0).getDeviceTypeDictMap());
       long totalCount = responseResult.getData().getTotalCount();
       log.info("打印totalCount:{}",totalCount);


       return ResponseResult.success(MyPageUtil.makeResponseData(paperExerciseTransList, PaperExerciseTrans.INSTANCE));

   }

   @GetMapping("/view")
   public ResponseResult<PaperExerciseTransVo> view(@RequestParam Long transId) {

       if(MyCommonUtil.existBlankArgument(transId)){
           return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
       }

       PaperExerciseTrans exerciseTrans =
               paperExerciseTransService.getByIdWithRelation(transId, MyRelationParam.full());

       if (exerciseTrans == null) {
          return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
       }

       PaperExerciseTransVo transVo = PaperExerciseTrans.INSTANCE.fromModel(exerciseTrans);

       return ResponseResult.success(transVo);
   }

   @OperationLog(type = SysOperationLogType.UPDATE)
   @PostMapping("/update")
   public ResponseResult<Void> update(@MyRequestBody PaperExerciseTransDto orgPaperDto){
        PaperExerciseTrans trans = MyModelUtil.copyTo(orgPaperDto,PaperExerciseTrans.class);
        PaperExerciseTrans orgTrans = paperExerciseTransService.getById(trans.getTransId());
        if (orgTrans == null) {
            String errorMessage2 = "数据验证失败，当前 [数据] 并不存在，请刷新后重试！";
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage2);
        }
       CallResult callResult = paperExerciseTransService.verifyRelatedData(trans,orgTrans);
       if(!callResult.isSuccess()){
           return ResponseResult.errorFrom(callResult);
       }
       if(!paperExerciseTransService.update(trans,orgTrans)) {
           return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
       }
       return ResponseResult.success();
   }

    /**
     * 新增数据
     * @param orgPaperDto
     * @return
     */
   @PostMapping("/add")
   public ResponseResult<Long> add(@MyRequestBody PaperExerciseTransDto orgPaperDto){

//       String errorMsg = MyCommonUtil.getModelValidationError(orgPaperDto,false);
//       if(errorMsg != null){
//           return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED,errorMsg);
//       }

       PaperExerciseTrans trans = MyModelUtil.copyTo(orgPaperDto,PaperExerciseTrans.class);

//       CallResult callResult = paperExerciseTransService.verifyRelatedData(trans,null);
//       if(!callResult.isSuccess()){
//           return ResponseResult.errorFrom(callResult);
//       }

       trans = paperExerciseTransService.saveNew(trans);
       return ResponseResult.success(trans.getTransId());

   }

   @PostMapping("/delete")
   public ResponseResult<Void> delete(@MyRequestBody Long id){
       if(MyCommonUtil.existBlankArgument(id)){
           return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
       }
       return this.doDelete(id);
   }

    /**
     * 文件上传操作。
     *
     * @param fieldName  上传文件名。
     * @param asImage    是否作为图片上传。如果是图片，今后下载的时候无需权限验证。否则就是附件上传，下载时需要权限验证。
     * @param uploadFile 上传文件对象。
     */
   @PostMapping("/upload")
   public void upload(
           @RequestParam String fieldName,
           @RequestParam Boolean asImage,
           @RequestParam("uploadFile") MultipartFile uploadFile) throws Exception {

       log.info("打印upload fieldName:{}",fieldName);
       UploadStoreInfo storeInfo = MyModelUtil.getUploadStoreInfo(PaperExerciseTrans.class,fieldName);
       // 这里就会判断参数中指定的字段，是否支持上传操作。
       if(!storeInfo.isSupportUpload()){
           ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                   ResponseResult.error(ErrorCodeEnum.INVALID_TENANT_CODE));
           return;
       }
       // 根据字段注解中的存储类型，通过工厂方法获取匹配的上传下载实现类，从而解耦。
       BaseUpDownloader upDownloader = upDownloaderFactory.get(storeInfo.getStoreType());
       UploadResponseInfo responseInfo = upDownloader.doUpload(null,
               appConfig.getUploadFileBaseDir(),PaperExerciseTrans.class.getSimpleName(),fieldName,asImage,uploadFile);
       if (responseInfo.getUploadFailed()) {
           ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                   ResponseResult.error(ErrorCodeEnum.UPLOAD_FAILED,responseInfo.getErrorMessage()));
           return;
       }
       cacheHelper.putSessionUploadFile(responseInfo.getFilename());
       ResponseResult.output(ResponseResult.success(responseInfo));
   }

   @GetMapping("/download")
   public void download(
           @RequestParam(required = false) Long id,
           @RequestParam String fieldName,
           @RequestParam String filename,
           @RequestParam Boolean asImage,
           HttpServletResponse response
   ){
       if(MyCommonUtil.existBlankArgument(fieldName,filename,asImage)){
           response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
           return;
       }
       // 使用try来捕获异常，是为了保证一旦出现异常可以返回500的错误状态，便于调试。
       // 否则有可能给前端返回的是200的错误码。
       try {
           if(id == null){
               if (!cacheHelper.existSessionUploadFile(filename)) {
                   ResponseResult.output(HttpServletResponse.SC_FORBIDDEN);
                   return;
               }
           } else {
               PaperExerciseTrans trans = paperExerciseTransService.getById(id);
               if(trans == null){
                   ResponseResult.output(HttpServletResponse.SC_NOT_FOUND);
                   return;
               }
               String fieldJsonData = (String) ReflectUtil.getFieldValue(trans, fieldName);
               if (fieldJsonData == null) {
                   ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST);
                   return;
               }
               if (!BaseUpDownloader.containFile(fieldJsonData, filename)) {
                   ResponseResult.output(HttpServletResponse.SC_FORBIDDEN);
                   return;
               }
           }
           UploadStoreInfo storeInfo = MyModelUtil.getUploadStoreInfo(PaperExerciseTrans.class, fieldName);
           if (!storeInfo.isSupportUpload()) {
               ResponseResult.output(HttpServletResponse.SC_NOT_IMPLEMENTED,
                       ResponseResult.error(ErrorCodeEnum.INVALID_UPLOAD_FIELD));
               return;
           }
           BaseUpDownloader upDownloader = upDownloaderFactory.get(storeInfo.getStoreType());
           upDownloader.doDownload(appConfig.getUploadFileBaseDir(),
                   PaperExerciseTrans.class.getSimpleName(), fieldName, filename, asImage, response);
       }catch (Exception e){
           response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
           log.error(e.getMessage(),e);
       }
   }

   private ResponseResult<Void> doDelete(Long id){
       String errorMessage;
       PaperExerciseTrans trans = paperExerciseTransService.getById(id);
       if(trans == null){
           errorMessage = "数据验证失败，当前 [对象] 并不存在，请刷新后重试！";
           return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST,errorMessage);
       }
       if(!paperExerciseTransService.remove(id)){
           errorMessage = "数据操作失败，删除的对象不存在，请刷新后重试！";
           return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST,errorMessage);
       }
       return ResponseResult.success();
   }



}
